﻿using DataAccess;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.FileProviders;
using MyPetHub.Controllers;
using MyPetHub.Filters;
using MyPetHub.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.ComponentModel.DataAnnotations;
using System.Configuration;
using System.Dynamic;
using System.Linq.Expressions;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Transactions;
using System.Xml.Linq;

namespace MyPetHub.Areas.SuperAdmin.Controllers
{
    [Area("Super")]
    [AdminAuthorizationFilter]
    public class SuperHomeController : BaseController
    {
        IConfiguration configuration;
        IFileProvider ifpObj;
        int perPageCount = 20;
        int videoSize = 5;//5M
        int imgSize = 1;//1M
       static   Expression<Func<PetStory, dynamic>> petStoryFunc;
        static Expression<Func<PetKnowledge, dynamic>> petKnowledgeFunc;
        static Expression<Func<MerchantInfo, dynamic>> merchantFunc;
        static Expression<Func<AdvertInfo, dynamic>> advertFunc;

        static SuperHomeController()
        {
            //生成宠物故事表达式
            petStoryFunc = (x) => new
            {
                dataid = x.id,
                date = x.updatetime.ToString("yyyy-MM-dd HH:mm"),
                title = x.title,
                subtitle = x.subtitle,
                species = speciesinfoDict[x.speciesid ?? 1],
                isrecommended = x.isrecommended
            };

            //生成养宠知识表达式
            petKnowledgeFunc = (x) => new
            {
                dataid = x.id,
                date = x.updatetime.ToString("yyyy-MM-dd HH:mm"),
                title = x.title,
                subtitle = x.subtitle,
                species = speciesinfoDict[x.speciesid ?? 1],
                isrecommended = x.isrecommended
            };

            //生成商户信息表达式
            merchantFunc = (x) => new
            {
                dataid = x.id,
                date = x.updatetime.ToString("yyyy-MM-dd HH:mm"),
                code = x.code,
                name = x.name,
                phone = x.phone,
                address = x.address,
                contact = x.contact,
                status = x.status
            };

            //生成广告信息表达式
            advertFunc = (x) => new
            {
                dataid = x.id,
                date = x.updatetime.ToString("yyyy-MM-dd HH:mm"),
                customerName = x.customername,
                customerPhone = x.customerphone,
                price = x.price,
                endDate = x.enddate.ToString("yyyy-MM-dd"),
                isShow = x.isshow,
                advertType = x.isblock == false ? "横幅" : "块状",
                readCount = x.readcount,
                advertUrl = x.adverturl
            };
        }

        public SuperHomeController(MyPetHubContext dbContext, IMemoryCache mcObj, IHttpContextAccessor httpContextAccessor, IFileProvider ifp, IConfiguration configuration) : base(mcObj, dbContext, httpContextAccessor)
        {
            this.ifpObj = ifp;
            this.configuration = configuration;
            perPageCount = configuration.GetValue<int>("PerPageCount");//宠物信息每页数据量
            videoSize = configuration.GetValue<int>("videoSize");//视频大小
            imgSize = configuration.GetValue<int>("imgSize");//图片大小

            //模拟登陆！！！！！！！！！！！！
            //SHA256 mySHA256 = SHA256.Create();
            //string shaPwd = BitConverter.ToString(mySHA256.ComputeHash(UnicodeEncoding.UTF8.GetBytes("123456")));

            //SysUser? suObj = dbContext.SysUser.Where(x => x.merchantid == merID && x.account == "lyp123" && x.password == shaPwd).FirstOrDefault();
            //httpContextAccessor.HttpContext.Session.SetString("SysUser", JsonConvert.SerializeObject(suObj, formatSettings));

            //防止冒充其他的商家
            if (httpContextAccessor.HttpContext.Session.GetString("SysUser") != null)
            {
                SysUser? mm = JsonConvert.DeserializeObject<SysUser>(httpContextAccessor.HttpContext.Session.GetString("SysUser"));
                if (mm.merchantid != merID)
                    throw new Exception("身份验证失败");

                if (mm.adminlevel != 0)
                    throw new Exception("权限验证失败");
            }
        }

        //宠物故事
        [AdminHomeActionFilter]
        public async Task<IActionResult> Index()
        {
            ViewData["Title"] = "爱宠故事";

            var speciesList = speciesinfoDict.Select(x => new { id = x.Key, name = x.Value }).ToList();
            ViewData["speciesList"] = JsonConvert.SerializeObject(speciesList, formatSettings);

            ViewData["pageSize"] = perPageCount;
            ViewData["videoSize"] = videoSize;
            ViewData["imgSize"] = imgSize;
            ViewData["dataType"] = 1;

            ViewData["defaultMenuActive"] = 1;
            return View();
        }

        [HttpPost]
        public async Task<string> AddOrUpdatePetStory()
        {
            //名称重复判断
            JObject jobj = JObject.Parse(Request.Form["textData"].ToString());
            string dataType = jobj["dataType"].ToString();

            if(dataType == "1")//宠物故事
            {
                return await AddOrUpdatePetStoryLogic();
            }
            else if(dataType == "2")//养宠知识
            {
                return await AddOrUpdatePetKnowledgeLogic();
            }

            return "数据类型错误";
        }

        private async Task<string> AddOrUpdatePetStoryLogic()
        {
            //名称重复判断
            JObject jobj = JObject.Parse(Request.Form["textData"].ToString());
            string dataid = jobj["dataid"].ToString();
            string title = jobj["title"].ToString();

            if (dataid == "-1")//添加
            {
                PetStory petStory = await dbContext.PetStory.Where(x =>  x.title == title).FirstOrDefaultAsync();
                if (petStory != null)
                {
                    return "标题重复";
                }
            }
            else
            {
                PetStory petStory = await dbContext.PetStory.Where(x => x.title == title && x.id != long.Parse(dataid)).FirstOrDefaultAsync();
                if (petStory != null)
                {
                    return "标题重复";
                }
            }

            //文件路径
            string imgPath = ifpObj.GetDirectoryContents("super").Where(x => x.Name == "imgs").First().PhysicalPath;
            string videoPath = ifpObj.GetDirectoryContents("super").Where(x => x.Name == "videos").First().PhysicalPath;

           Dictionary<string,string> srcDict =  await SaveFormFiles(imgPath,videoPath,Request);

            string coverImgSrc = srcDict["coverImgSrc"];
            string videoSrc = srcDict["videoSrc"];
            string otherImgSrc = srcDict["otherImgSrc"];

            //保存数据
            using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                PetStory petStory;
                if (dataid == "-1")//添加
                {
                    petStory = new PetStory();
                    petStory.id = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmssfff"));
                    petStory.readcount = 0;
                    petStory.videosrc = videoSrc;
                }
                else//编辑
                {
                    petStory = await dbContext.PetStory.Where(x =>  x.id == long.Parse(dataid)).FirstOrDefaultAsync();

                    if (string.IsNullOrEmpty(videoSrc))//没有更改视频
                    {
                        DeleteOldFile(petStory, imgPath, videoPath, false);//不删除视频文件
                    }
                    else
                    {
                        DeleteOldFile(petStory, imgPath, videoPath, true);
                        petStory.videosrc = videoSrc;
                    }
                }

                petStory.title = title;
                petStory.subtitle = jobj["subTitle"].ToString();
                petStory.content = jobj["content"].ToString();
                petStory.speciesid = int.Parse(jobj["selectedSpeciesItem"].ToString());
                petStory.isrecommended = jobj["isRecommend"].ToString() == "1" ? false : true;
                petStory.coverimgsrc = coverImgSrc;
                petStory.otherimgsrc = otherImgSrc;
                petStory.updatetime = DateTime.Now;

                if (dataid == "-1")//添加
                {
                    await dbContext.PetStory.AddAsync(petStory);
                }

                await dbContext.SaveChangesAsync();
                scope.Complete();
            }

            return "ok";
        }

        private async Task<string> AddOrUpdatePetKnowledgeLogic()
        {
            //名称重复判断
            JObject jobj = JObject.Parse(Request.Form["textData"].ToString());
            string dataid = jobj["dataid"].ToString();
            string title = jobj["title"].ToString();

            if (dataid == "-1")//添加
            {
                PetKnowledge petKnowledge = await dbContext.PetKnowledge.Where(x => x.title == title).FirstOrDefaultAsync();
                if (petKnowledge != null)
                {
                    return "标题重复";
                }
            }
            else
            {
                PetKnowledge petKnowledge = await dbContext.PetKnowledge.Where(x => x.title == title && x.id != long.Parse(dataid)).FirstOrDefaultAsync();
                if (petKnowledge != null)
                {
                    return "标题重复";
                }
            }

            //文件路径
            string imgPath = ifpObj.GetDirectoryContents("super").Where(x => x.Name == "imgs").First().PhysicalPath;
            string videoPath = ifpObj.GetDirectoryContents("super").Where(x => x.Name == "videos").First().PhysicalPath;

            Dictionary<string, string> srcDict = await SaveFormFiles(imgPath, videoPath, Request);

            string coverImgSrc = srcDict["coverImgSrc"];
            string videoSrc = srcDict["videoSrc"];
            string otherImgSrc = srcDict["otherImgSrc"];

            //保存数据
            using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                PetKnowledge petKnowledge;
                if (dataid == "-1")//添加
                {
                    petKnowledge = new PetKnowledge();
                    petKnowledge.id = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmssfff"));
                    petKnowledge.readcount = 0;
                    petKnowledge.videosrc = videoSrc;
                }
                else//编辑
                {
                    petKnowledge = await dbContext.PetKnowledge.Where(x => x.id == long.Parse(dataid)).FirstOrDefaultAsync();

                    if (string.IsNullOrEmpty(videoSrc))//没有更改视频
                    {
                        DeleteOldFile(petKnowledge, imgPath, videoPath, false);//不删除视频文件
                    }
                    else
                    {
                        DeleteOldFile(petKnowledge, imgPath, videoPath, true);
                        petKnowledge.videosrc = videoSrc;
                    }
                }

                petKnowledge.title = title;
                petKnowledge.subtitle = jobj["subTitle"].ToString();
                petKnowledge.content = jobj["content"].ToString();
                petKnowledge.speciesid = int.Parse(jobj["selectedSpeciesItem"].ToString());
                petKnowledge.isrecommended = jobj["isRecommend"].ToString() == "1" ? false : true;
                petKnowledge.coverimgsrc = coverImgSrc;
                petKnowledge.otherimgsrc = otherImgSrc;
                petKnowledge.updatetime = DateTime.Now;

                if (dataid == "-1")//添加
                {
                    await dbContext.PetKnowledge.AddAsync(petKnowledge);
                }

                await dbContext.SaveChangesAsync();
                scope.Complete();
            }

            return "ok";
        }

        [HttpPost]
        public async Task<ActionResult> GetPetStoryOrKnowledgeByID([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            long dataid = long.Parse(jobj["dataid"].ToString());
            string dataType = jobj["dataType"].ToString();

            if(dataType == "1")
            {
                PetStory petStory = await dbContext.PetStory.Where(x => x.id == dataid).FirstOrDefaultAsync();
                return new JsonResult(petStory);
            }
            else
            {
                PetKnowledge petKnowledge = await dbContext.PetKnowledge.Where(x => x.id == dataid).FirstOrDefaultAsync();
                return new JsonResult(petKnowledge);
            }
        }

        [HttpPost]
        public async Task<string> ChangeRecommendStatus([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            long dataid = long.Parse(jobj["dataid"].ToString());
            string dataType = jobj["dataType"].ToString();
            bool recom = bool.Parse(jobj["isRecom"].ToString());

            if (dataType == "1")
            {
                PetStory petStory = await dbContext.PetStory.Where(x => x.id == dataid).FirstOrDefaultAsync();
                petStory.isrecommended = recom;
                petStory.updatetime = DateTime.Now;
            }
            else
            {
                PetKnowledge petKnowledge = await dbContext.PetKnowledge.Where(x => x.id == dataid).FirstOrDefaultAsync();
                petKnowledge.isrecommended = recom;
                petKnowledge.updatetime = DateTime.Now;
            }

            await dbContext.SaveChangesAsync();
            return "ok";
        }

        //删除宠物故事或养宠知识
        [HttpPost]
        public async Task<string> DeletePetStoryOrKnowledge([FromBody] object json)
        {
            //名称重复判断
            JObject jobj = JObject.Parse(json.ToString());
            string dataids = jobj["dataids"].ToString();
            string dataType = jobj["dataType"].ToString();
            string[] idArray = dataids.Split('|');

            //文件路径
            string imgPath = ifpObj.GetDirectoryContents("super").Where(x => x.Name == "imgs").First().PhysicalPath;
            string videoPath = ifpObj.GetDirectoryContents("super").Where(x => x.Name == "videos").First().PhysicalPath;

            if(dataType == "1")
            {
                List<PetStory> pis = new List<PetStory>();
                foreach (string id in idArray)
                {
                    var petStory = await dbContext.PetStory.Where(x => x.id == long.Parse(id)).FirstOrDefaultAsync();
                    DeleteOldFile(petStory, imgPath, videoPath);

                    pis.Add(petStory);
                }

                dbContext.PetStory.RemoveRange(pis);
            }
            else
            {
                List<PetKnowledge> pis = new List<PetKnowledge>();
                foreach (string id in idArray)
                {
                    var petKnowledge = await dbContext.PetKnowledge.Where(x => x.id == long.Parse(id)).FirstOrDefaultAsync();
                    DeleteOldFile(petKnowledge, imgPath, videoPath);

                    pis.Add(petKnowledge);
                }

                dbContext.PetKnowledge.RemoveRange(pis);
            }

            await dbContext.SaveChangesAsync();

            return "ok";
        }

        //获取文件
        [HttpPost]
        public ActionResult DownFile([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            string fileName = jobj["fileName"].ToString();
            string lastName = fileName.Substring(fileName.LastIndexOf('.')).ToLower();//后缀名

            string filePath = "";
            if (allowedImgList.Contains(lastName))
            {
                filePath = ifpObj.GetDirectoryContents("super").Where(x => x.Name == "imgs").First().PhysicalPath;
            }
            else if (allowedVideoList.Contains(lastName))
            {
                filePath = ifpObj.GetDirectoryContents("super").Where(x => x.Name == "videos").First().PhysicalPath;
            }

            using (var stream = new FileStream(filePath + "/" + fileName, FileMode.Open))
            {
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);
                stream.Seek(0, SeekOrigin.Begin); // 设置当前流的位置为流的开始

                return new FileContentResult(bytes, "application/octet-stream");
            }
        }

        //宠物数据分页
        [HttpPost]
        public async Task<JsonResult> GetPaginationInfo([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            string dataType = jobj["dataType"].ToString();

            PaginationData<List<dynamic>> paginationData = new PaginationData<List<dynamic>> ();
            if(dataType == "1")//宠物故事
            {
                paginationData = await GetPetStoryPageData(jobj);
            }
            else if(dataType == "2")
            {
                paginationData = await GetPetStoryKnowledgeData(jobj);
            }

            return new JsonResult(paginationData);
        }

        //清除推荐
        [HttpPost]
        public async Task<string> ClearRecommend([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            long dataid =long.Parse(jobj["dataid"].ToString());
            bool isRecom = bool.Parse(jobj["isRecom"].ToString());
            string dataType = jobj["dataType"].ToString();

            if (dataType == "1")
            {
                List<PetStory> petStorys = new List<PetStory>();
                if(dataid == -1)//全部清除
                {
                    petStorys = await dbContext.PetStory.Where(x => x.isrecommended == true).ToListAsync();
                }
                else
                {
                    petStorys = await dbContext.PetStory.Where(x => x.id == dataid).ToListAsync();
                }

                petStorys.ForEach(x => { x.isrecommended = isRecom; x.updatetime = DateTime.Now; });
            }
            else
            {
                List<PetKnowledge> petKnowledges = new List<PetKnowledge>();
                if (dataid == -1)//全部清除
                {
                    petKnowledges = await dbContext.PetKnowledge.Where(x => x.isrecommended == true).ToListAsync();
                }
                else
                {
                    petKnowledges = await dbContext.PetKnowledge.Where(x => x.id == dataid).ToListAsync();
                }

                petKnowledges.ForEach(x => { x.isrecommended = isRecom;x.updatetime = DateTime.Now; }) ;
            }

            await dbContext.SaveChangesAsync();
            return "ok";
        }

        //宠物故事分页
        private async  Task<PaginationData<List<dynamic>>> GetPetStoryPageData(JObject jobj)
        {
            int pageNum = int.Parse(jobj["pageNum"].ToString());
            string titleOrSubTitle = jobj["titleOrSubTitle"].ToString();
            int specialsNum = int.Parse(jobj["specialsNum"].ToString());

            PaginationData<List<dynamic>> paginationData = new PaginationData<List<dynamic>>();
            List<dynamic> petInfo = null;
            int dataCount = 0;
            if (specialsNum == 0)//全部种类
            {
                if (string.IsNullOrEmpty(titleOrSubTitle))//无搜索条件
                {
                    dataCount = await dbContext.PetStory.CountAsync();
                    petInfo = await dbContext.PetStory.OrderByDescending(x => x.isrecommended).ThenByDescending(x => x.updatetime).
                        Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(petStoryFunc).ToListAsync();
                }
                else
                {
                    dataCount = await dbContext.PetStory.Where(x=>x.title.Contains(titleOrSubTitle) || x.subtitle.Contains(titleOrSubTitle)).CountAsync();
                    petInfo = await dbContext.PetStory.Where(x => x.title.Contains(titleOrSubTitle) || x.subtitle.Contains(titleOrSubTitle)).OrderByDescending(x => x.isrecommended).ThenByDescending(x => x.updatetime).
                        Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(petStoryFunc).ToListAsync();
                }
            }
            else
            {
                if (string.IsNullOrEmpty(titleOrSubTitle))//无搜索条件
                {
                    dataCount = await dbContext.PetStory.Where(x=>x.speciesid == specialsNum).CountAsync();
                    petInfo = await dbContext.PetStory.Where(x => x.speciesid == specialsNum).OrderByDescending(x => x.isrecommended).ThenByDescending(x => x.updatetime).
                        Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(petStoryFunc).ToListAsync();
                }
                else
                {
                    dataCount = await dbContext.PetStory.Where(x => x.speciesid == specialsNum && (x.title.Contains(titleOrSubTitle) || x.subtitle.Contains(titleOrSubTitle))).CountAsync();
                    petInfo = await dbContext.PetStory.Where(x => x.speciesid == specialsNum && (x.title.Contains(titleOrSubTitle) || x.subtitle.Contains(titleOrSubTitle)))
                        .OrderByDescending(x => x.isrecommended).ThenByDescending(x => x.updatetime).
                        Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(petStoryFunc).ToListAsync();
                }
            }

            paginationData.data = petInfo;
            paginationData.dataCount = dataCount;
            return paginationData;
        }

        //养宠知识分页
        private async Task<PaginationData<List<dynamic>>> GetPetStoryKnowledgeData(JObject jobj)
        {
            int pageNum = int.Parse(jobj["pageNum"].ToString());
            string titleOrSubTitle = jobj["titleOrSubTitle"].ToString();
            int specialsNum = int.Parse(jobj["specialsNum"].ToString());

            PaginationData<List<dynamic>> paginationData = new PaginationData<List<dynamic>>();
            List<dynamic> petInfo = null;
            int dataCount = 0;
            if (specialsNum == 0)//全部种类
            {
                if (string.IsNullOrEmpty(titleOrSubTitle))//无搜索条件
                {
                    dataCount = await dbContext.PetKnowledge.CountAsync();
                    petInfo = await dbContext.PetKnowledge.OrderByDescending(x => x.isrecommended).ThenByDescending(x => x.updatetime).
                        Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(petKnowledgeFunc).ToListAsync();
                }
                else
                {
                    dataCount = await dbContext.PetKnowledge.Where(x => x.title.Contains(titleOrSubTitle) || x.subtitle.Contains(titleOrSubTitle)).CountAsync();
                    petInfo = await dbContext.PetKnowledge.Where(x => x.title.Contains(titleOrSubTitle) || x.subtitle.Contains(titleOrSubTitle)).OrderByDescending(x => x.isrecommended).ThenByDescending(x => x.updatetime).
                        Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(petKnowledgeFunc).ToListAsync();
                }
            }
            else
            {
                if (string.IsNullOrEmpty(titleOrSubTitle))//无搜索条件
                {
                    dataCount = await dbContext.PetKnowledge.Where(x => x.speciesid == specialsNum).CountAsync();
                    petInfo = await dbContext.PetKnowledge.Where(x => x.speciesid == specialsNum).OrderByDescending(x => x.isrecommended).ThenByDescending(x => x.updatetime).
                        Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(petKnowledgeFunc).ToListAsync();
                }
                else
                {
                    dataCount = await dbContext.PetKnowledge.Where(x => x.speciesid == specialsNum && (x.title.Contains(titleOrSubTitle) || x.subtitle.Contains(titleOrSubTitle))).CountAsync();
                    petInfo = await dbContext.PetKnowledge.Where(x => x.speciesid == specialsNum && (x.title.Contains(titleOrSubTitle) || x.subtitle.Contains(titleOrSubTitle)))
                        .OrderByDescending(x => x.isrecommended).ThenByDescending(x => x.updatetime).
                        Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(petKnowledgeFunc).ToListAsync();
                }
            }

            paginationData.data = petInfo;
            paginationData.dataCount = dataCount;
            return paginationData;
        }

        [AdminHomeActionFilter]
        public IActionResult PetKnowledge()
        {
            ViewData["Title"] = "养宠知识";

            var speciesList = speciesinfoDict.Select(x => new { id = x.Key, name = x.Value }).ToList();
            ViewData["speciesList"] = JsonConvert.SerializeObject(speciesList, formatSettings);

            ViewData["pageSize"] = perPageCount;
            ViewData["videoSize"] = videoSize;
            ViewData["imgSize"] = imgSize;
            ViewData["dataType"] = 2;

            ViewData["defaultMenuActive"] = 2;
            return View("Index");
        }

        //商户管理
        [AdminHomeActionFilter]
        public IActionResult MerchantManagement()
        {
            ViewData["pageSize"] = perPageCount;
            return View();
        }

        public async Task<PaginationData<List<dynamic>>> GetMerchantInfoPagination([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            int pageNum = int.Parse(jobj["pageNum"].ToString());
            string codeOrName = jobj["codeOrName"].ToString();

            PaginationData<List<dynamic>> paginationData = new PaginationData<List<dynamic>>();
            List<dynamic> merchantInfo = null;
            int dataCount = 0;

            if (string.IsNullOrEmpty(codeOrName))//无搜索条件
            {
                dataCount = await dbContext.MerchantInfo.CountAsync();
                merchantInfo = await dbContext.MerchantInfo.OrderByDescending(x => x.updatetime).
                    Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(merchantFunc).ToListAsync();
            }
            else
            {
                dataCount = await dbContext.MerchantInfo.Where(x => x.code.Contains(codeOrName) || x.name.Contains(codeOrName)).CountAsync();
                merchantInfo = await dbContext.MerchantInfo.Where(x => x.code.Contains(codeOrName) || x.name.Contains(codeOrName)).OrderByDescending(x => x.updatetime).
                    Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(merchantFunc).ToListAsync();
            }

            paginationData.data = merchantInfo;
            paginationData.dataCount = dataCount;
            return paginationData;
        }

        [HttpPost]
        public async Task<string> AddOrUpdateMerchantInfo([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            long dataid = long.Parse(jobj["dataid"].ToString());
            string code = jobj["code"].ToString();

            if (dataid == -1)//添加
            {
                var miObj = await dbContext.MerchantInfo.Where(x => x.code == code).FirstOrDefaultAsync();
                if (miObj != null)
                {
                    return "商户代码重复";
                }
            }

            using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                long merchantid =  await HandleMerchantInfo(jobj);//商户信息处理
                await HandleSysUser(jobj, merchantid);//商户管理员处理

                await dbContext.SaveChangesAsync();
                scope.Complete();
            }

            return "ok";
        }

        private async Task<long> HandleMerchantInfo(JObject jobj)
        {
            long dataid = long.Parse(jobj["dataid"].ToString());
            string code = jobj["code"].ToString();
            string name = jobj["name"].ToString();
            string phone = jobj["phone"].ToString();
            string contact = jobj["contact"].ToString();
            string address = jobj["address"].ToString();
            bool status = jobj["status"].ToString() == "1" ? true : false;

            MerchantInfo miObj = null;
            if (dataid == -1)//添加
            {
                miObj = new MerchantInfo();
                miObj.id = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmssfff"));
            }
            else
            {
                miObj = await dbContext.MerchantInfo.Where(x => x.id == dataid).FirstOrDefaultAsync();
            }

            miObj.code = code;
            miObj.name = name;
            miObj.phone = phone;
            miObj.contact = contact;
            miObj.address = address;
            miObj.status = status;
            miObj.updatetime = DateTime.Now;

            if (dataid == -1)
            {
                //添加code文件路径 
               var fileInfo =  ifpObj.GetDirectoryContents(code).FirstOrDefault();
               if (fileInfo != null)
                {
                    throw new Exception(code+"目录已经存在！");
                }

                string directoryPath = configuration.GetSection("Dev").GetSection("StaticFilePath").Value + "/" + code;
                Directory.CreateDirectory(directoryPath);
                Directory.CreateDirectory(directoryPath+"/imgs");
                Directory.CreateDirectory(directoryPath + "/videos");

                await dbContext.MerchantInfo.AddAsync(miObj);
            }

            return miObj.id;
        }

        private async Task HandleSysUser(JObject jobj,long merchantid)
        {
            long accountid = long.Parse(jobj["accountid"].ToString());
            string account = jobj["account"].ToString();
            string nickName = jobj["nickName"].ToString();
            string password = jobj["password"].ToString();

            SHA256 mySHA256 = SHA256.Create();
            SysUser suObj = null;
            if (accountid == -1)//添加
            {
                suObj = new SysUser();
                suObj.merchantid = merchantid;
                suObj.userid = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmssfff"));

                string shaPwd = BitConverter.ToString(mySHA256.ComputeHash(UnicodeEncoding.UTF8.GetBytes(password)));
                suObj.password = shaPwd;
            }
            else
            {
                suObj = await dbContext.SysUser.Where(x => x.merchantid == merchantid && x.userid == accountid).FirstOrDefaultAsync();
                if(!string.IsNullOrEmpty(password))//更改密码
                {
                    string shaPwd = BitConverter.ToString(mySHA256.ComputeHash(UnicodeEncoding.UTF8.GetBytes(password)));
                    suObj.password = shaPwd;
                }
            }

            suObj.account = account;
            suObj.nickname = nickName;
            suObj.status = 0;
            suObj.adminlevel = 1;
            suObj.updatetime = DateTime.Now;

            if (accountid == -1)
            {
                await dbContext.SysUser.AddAsync(suObj);
            }
        }

        //获取商户和管理员数据
        [HttpPost]
        public async Task<JsonResult> GetMerchantInfo([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            long dataid =long.Parse(jobj["dataid"].ToString());

            var miObj = await dbContext.MerchantInfo.Where(x => x.id == dataid).FirstOrDefaultAsync();
            if (miObj == null)
            {
                throw new Exception("商户数据不存在:" + dataid);
            }

            var suObj = await dbContext.SysUser.Where(x => x.merchantid == miObj.id && x.adminlevel == 1).FirstOrDefaultAsync();
            dynamic dyObj = new ExpandoObject();

            dyObj.dataid = miObj.id;
            dyObj.date = miObj.updatetime.ToString("yyyy-MM-dd HH:mm");
            dyObj.code = miObj.code;
            dyObj.name = miObj.name;
            dyObj.phone = miObj.phone;
            dyObj.address = miObj.address;
            dyObj.contact = miObj.contact;
            dyObj.status = miObj.status == true ? 1 : 2;

            dyObj.accountid = suObj.userid;
            dyObj.account = suObj.account;
            dyObj.nickName = suObj.nickname;

            return new JsonResult(dyObj);
        }

        //启用/禁用账号信息
        [HttpPost]
        public async Task<string> ChangeAccountStatus([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            string dataids = jobj["dataids"].ToString();
            bool status = bool.Parse(jobj["status"].ToString());

            string[] idArray = dataids.Split('|');
            foreach (string id in idArray)
            {
                var miObj = await dbContext.MerchantInfo.Where(x => x.id == long.Parse(id)).FirstOrDefaultAsync();
                miObj.status = status;
            }

            await dbContext.SaveChangesAsync();
            return "ok";
        }

        //广告管理
        [AdminHomeActionFilter]
        public IActionResult AdvertManagement()
        {
            ViewData["pageSize"] = perPageCount;
            ViewData["imgSize"] = imgSize;
            return View();
        }

        //广告信息分页
        public async Task<PaginationData<List<dynamic>>> GetAdvertPagination([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            int pageNum = int.Parse(jobj["pageNum"].ToString());
            string customerName = jobj["customerName"].ToString();

            PaginationData<List<dynamic>> paginationData = new PaginationData<List<dynamic>>();
            List<dynamic> advertInfo = null;
            int dataCount = 0;

            if (string.IsNullOrEmpty(customerName))//无搜索条件
            {
                dataCount = await dbContext.AdvertInfo.CountAsync();
                advertInfo = await dbContext.AdvertInfo.OrderByDescending(x => x.isshow).
                    Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(advertFunc).ToListAsync();
            }
            else
            {
                dataCount = await dbContext.AdvertInfo.Where(x => x.customername.Contains(customerName)).CountAsync();
                advertInfo = await dbContext.AdvertInfo.Where(x => x.customername.Contains(customerName)).OrderByDescending(x => x.isshow).
                    Skip((pageNum - 1) * perPageCount).Take(perPageCount).Select(advertFunc).ToListAsync();
            }

            paginationData.data = advertInfo;
            paginationData.dataCount = dataCount;
            return paginationData;
        }

        //获取广告数据
        [HttpPost]
        public async Task<JsonResult> GetAdvertInfo([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            long dataid = long.Parse(jobj["dataid"].ToString());

            var advObj = await dbContext.AdvertInfo.Where(x => x.id == dataid).FirstOrDefaultAsync();
            if (advObj == null)
            {
                throw new Exception("广告数据不存在:" + dataid);
            }

            return new JsonResult(advObj);
        }

        [HttpPost]
        public async Task<string> AddOrUpdateAdvertInfo()
        {
            JObject jobj = JObject.Parse(Request.Form["textData"].ToString());
            string dataid = jobj["dataid"].ToString();

            //文件路径
            string imgPath = configuration.GetSection("Dev").GetSection("StaticFilePath").Value + "/super/adverts";
            Dictionary<string, string> srcDict = await SaveFormFiles(imgPath, "", Request);

            string coverImgSrc = srcDict["coverImgSrc"];
            AdvertInfo advertInfo;

            if (dataid == "-1")//添加
            {
                advertInfo = new AdvertInfo();
                advertInfo.id = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmssfff"));
                advertInfo.readcount = 0;
            }
            else//编辑
            {
                advertInfo = await dbContext.AdvertInfo.Where(x => x.id == long.Parse(dataid)).FirstOrDefaultAsync();
            }

            advertInfo.customername = jobj["customerName"].ToString();
            advertInfo.customerphone = jobj["customerPhone"].ToString();
            advertInfo.price = double.Parse(jobj["price"].ToString());
            advertInfo.enddate = DateTime.Parse(jobj["endDate"].ToString());
            advertInfo.isshow = jobj["isShow"].ToString() == "1" ? true : false;
            advertInfo.isblock = jobj["advertType"].ToString() == "1" ? false : true;
            advertInfo.imgsrc = coverImgSrc;
            advertInfo.adverturl = jobj["advertUrl"].ToString();
            advertInfo.updatetime = DateTime.Now;

            if (dataid == "-1")//添加
            {
                await dbContext.AdvertInfo.AddAsync(advertInfo);
            }

            await dbContext.SaveChangesAsync();
            return "ok";
        }

        //获取文件
        [HttpPost]
        public ActionResult DownAdvertFile([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            string fileName = jobj["fileName"].ToString();
            string lastName = fileName.Substring(fileName.LastIndexOf('.')).ToLower();//后缀名

            string filePath = "";
            if (allowedImgList.Contains(lastName))
            {
                filePath = configuration.GetSection("Dev").GetSection("StaticFilePath").Value + "/super/adverts";
            }
            else
            {
                throw new Exception($"广告图片不存在{fileName}");
            }

            using (var stream = new FileStream(filePath + "/" + fileName, FileMode.Open))
            {
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);
                stream.Seek(0, SeekOrigin.Begin); // 设置当前流的位置为流的开始

                return new FileContentResult(bytes, "application/octet-stream");
            }
        }

        //启用/禁用广告
        [HttpPost]
        public async Task<string> ChangeAdvertStatus([FromBody] object json)
        {
            JObject jobj = JObject.Parse(json.ToString());
            string dataids = jobj["dataids"].ToString();
            bool status = bool.Parse(jobj["status"].ToString());

            string[] idArray = dataids.Split('|');
            foreach (string id in idArray)
            {
                var miObj = await dbContext.AdvertInfo.Where(x => x.id == long.Parse(id)).FirstOrDefaultAsync();
                miObj.isshow = status;
            }

            await dbContext.SaveChangesAsync();
            return "ok";
        }
    }
}
